package utils

import (
	"crypto/md5"
	"encoding/hex"
	"net/url"
	"os"
	"path/filepath"
	"strings"

	"github.com/PuerkitoBio/goquery"
)

// 检查文件是否为HTML文件
func isHTMLFile(filePath string) bool {
	ext := strings.ToLower(filepath.Ext(filePath))
	return ext == ".html" || ext == ".htm" || ext == ""
}

// 从HTML文件中提取链接和资源
func extractLinksAndResources(filePath, baseURL string) ([]string, []string, error) {
	// 读取文件内容
	file, err := os.Open(filePath)
	if err != nil {
		return nil, nil, err
	}
	defer file.Close()

	// 使用goquery解析HTML
	doc, err := goquery.NewDocumentFromReader(file)
	if err != nil {
		return nil, nil, err
	}

	baseURLObj, err := url.Parse(baseURL)
	if err != nil {
		return nil, nil, err
	}

	links := make([]string, 0)
	resources := make([]string, 0)

	// 提取链接 (a标签)
	doc.Find("a").Each(func(i int, s *goquery.Selection) {
		href, exists := s.Attr("href")
		if exists {
			absURL := resolveURL(baseURLObj, href)
			if absURL != "" && isSameDomain(baseURLObj, absURL) {
				links = append(links, absURL)
			}
		}
	})

	// 提取图片 (img标签)
	doc.Find("img").Each(func(i int, s *goquery.Selection) {
		src, exists := s.Attr("src")
		if exists {
			absURL := resolveURL(baseURLObj, src)
			if absURL != "" {
				resources = append(resources, absURL)
			}
		}
	})

	// 提取CSS (link标签)
	doc.Find("link").Each(func(i int, s *goquery.Selection) {
		rel, _ := s.Attr("rel")
		href, exists := s.Attr("href")
		if exists && strings.ToLower(rel) == "stylesheet" {
			absURL := resolveURL(baseURLObj, href)
			if absURL != "" {
				resources = append(resources, absURL)
			}
		}
	})

	// 提取JavaScript (script标签)
	doc.Find("script").Each(func(i int, s *goquery.Selection) {
		src, exists := s.Attr("src")
		if exists {
			absURL := resolveURL(baseURLObj, src)
			if absURL != "" {
				resources = append(resources, absURL)
			}
		}
	})

	// 提取视频和音频 (video, audio标签)
	doc.Find("video source, audio source").Each(func(i int, s *goquery.Selection) {
		src, exists := s.Attr("src")
		if exists {
			absURL := resolveURL(baseURLObj, src)
			if absURL != "" {
				resources = append(resources, absURL)
			}
		}
	})

	// 提取CSS中的URL (内联样式和样式表)
	doc.Find("style").Each(func(i int, s *goquery.Selection) {
		cssText := s.Text()
		cssURLs := extractCSSURLs(cssText, baseURLObj)
		resources = append(resources, cssURLs...)
	})

	// 去重
	links = removeDuplicates(links)
	resources = removeDuplicates(resources)

	return links, resources, nil
}

// 检查URL是否属于同一域名
func isSameDomain(baseURL *url.URL, urlStr string) bool {
	u, err := url.Parse(urlStr)
	if err != nil {
		return false
	}
	return u.Hostname() == baseURL.Hostname()
}

// 去除重复项
func removeDuplicates(urls []string) []string {
	seen := make(map[string]bool)
	result := make([]string, 0, len(urls))

	for _, u := range urls {
		// 计算URL的MD5作为唯一标识
		hasher := md5.New()
		hasher.Write([]byte(u))
		urlHash := hex.EncodeToString(hasher.Sum(nil))

		if !seen[urlHash] {
			seen[urlHash] = true
			result = append(result, u)
		}
	}

	return result
}
